Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make canvas selectable / keyboard binding implicit #662

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from

Conversation

nikku
Copy link
Member

@nikku nikku commented Aug 15, 2022

This PR ships the foundations to support cross-browser/application copy and paste:

For demonstration purpose checkout application integration example in form-js.

This ensures a predictable editing experience, simplifies the keyboard and ensures worry free interoperability with multiple editors and inputs on the page.


Previous calls to keyboard.bind(someElement) or configuration via keyboard.bindTo log a descriptive descriptive error:

image


Closes #661

@bpmn-io-tasks bpmn-io-tasks bot added the needs review Review pending label Aug 15, 2022
@nikku
Copy link
Member Author

nikku commented Aug 16, 2022

This can be tried out via:

npx @bpmn-io/sr nikku/bpmn-js-native-copy-paste#keyboard-bind -c "npm run start"

What I did is to remove any input quirks but rely on canvas to be actually browser selected. As a side-effect though that means that we consistently need to select the canvas when modeling operations happen:

capture IH2DTf_optimized

I do not see a simple way to accomplish this (yet).


At this point we have two options:

  • 🅰️ ditch this approach and keep existing manual keybinding
  • 🅱️ invest into consistently + properly re-focus the canvas

🅱️ is a requirement for cross browser copy + paste to work reliably so I'd argue we need to pursue this route anyway.

@nikku
Copy link
Member Author

nikku commented Aug 16, 2022

The following shows how we may mitigate this: Whenever the canvas is mouse hovered we re-focus the canvas.

For debugging purposes I added a solid blue focus outline (solid blue => receives keyboard events + can copy + paste).

capture 3jv7hP_optimized


Try out via

npx @bpmn-io/sr nikku/bpmn-js-native-copy-paste#keyboard-bind -c "npm run start"

@barmac
Copy link
Member

barmac commented Aug 16, 2022

On MacOS, the focus state is persisted once I hover the canvas even if switch tab afterwards and come back. Is this is supposed to work like this? I am not opinionated but it would be logical to me that focus fades away when I move mouse outside without clicking.

@barmac
Copy link
Member

barmac commented Aug 16, 2022

Cf. recording

Screen.Recording.2022-08-16.at.17.00.18.mov

@nikku
Copy link
Member Author

nikku commented Aug 16, 2022

#662 (comment)

I guess so. Keyboard inputs also don't magically unfocus once you leave with the mouse. The existing implementation works in the exact same way, or at least should work in the same way.

@barmac
Copy link
Member

barmac commented Aug 16, 2022

Hmm I don't like the infinite scrolling of the canvas which triggers once you paste outside of the canvas, but this solution is still an improvement compared to what we have right now. Thus, 👍 from me.

@nikku
Copy link
Member Author

nikku commented Aug 16, 2022

Fortunately infinite scrolling is an existing feature (cf. demo.bpmn.io):

capture e4fk9B_optimized

@barmac
Copy link
Member

barmac commented Aug 16, 2022

Indeed, it's an out of scope feature to be fixed 😆

@marstamm
Copy link
Contributor

When we implicitly bind to the canvas, does it imply that extensions that rely on the command stack need to catch and trigger undo/redo manually? I'm thinking about the Properties panel here, where the most common case was to bind the keyboard to a common container.

I tested it on Edge and it works as expected, no new issues found from my side

@nikku
Copy link
Member Author

nikku commented Aug 16, 2022

When we implicitly bind to the canvas, does it imply that extensions that rely on the command stack need to catch and trigger undo/redo manually?

Exactly. The related hacks are all gone from the code base. If you want to trigger undo/redo via keyboard shortcuts you have to implement that yourself (i.e. attach a respective listener on the properties panel).

@nikku
Copy link
Member Author

nikku commented Aug 17, 2022

@philippfromme Given that there is a little bit of blinking during focus/unfocus going on we could decide to ditch the focus outline. What do you think?

@barmac
Copy link
Member

barmac commented Aug 17, 2022

While I was able to break the focus-on-hover on Safari, it's due to some element.hover bug – which is IMO an edge case we shouldn't care about.

Screen.Recording.2022-08-17.at.10.59.15.mov

Regarding the cross-browser copy and paste, on MacOS I am able to copy and paste across single browser tabs or even windows, but I cannot do that between different browsers (Safari -> Chrome, Chrome -> Safari). The clipboardData appeared to be empty when I tried to debug it.

@nikku nikku marked this pull request as draft August 17, 2022 13:11
@bpmn-io-tasks bpmn-io-tasks bot added in progress Currently worked on and removed needs review Review pending labels Aug 17, 2022
@nikku
Copy link
Member Author

nikku commented Aug 17, 2022

Found the following issues integration testing this against different libraries in our eco-system:

  • dmn-js-drd: no issues (works out of the box)
  • dmn-js-decision-table / literal expression editor: has it's own keyboard implementation ➡️ needs porting to similar bind behavior, i.e. either make the table selectable + bind to it.
  • form-js: re-uses diagram-js keyboard but has no canvas ➡️ need to improve the bind / unbind behavior proposed in this PR to get the actual diagram container. Two ideas:
    • expose diagram with container in form-js, too
    • pass the container on diagram.init for components to catch it and do stuff with it (i.e . register/unregister key bindings)

@pinussilvestrus
Copy link
Contributor

form-js: re-uses diagram-js keyboard but has no canvas ➡️ need to improve the bind / unbind behavior proposed in this PR to get the actual diagram container. Two ideas:

  • expose diagram with container in form-js, too
  • pass the container on diagram.init for components to catch it and do stuff with it (i.e . register/unregister key bindings)

Given we follow one of these approaches, would we also have to follow up with explicit keyboard bindings for the Forms Properties Panel?

I'm asking because we plan to make it independent from the editor (e.g. render it in an own container, as we do with the other properties panels, cf. bpmn-io/form-js#291).

@nikku
Copy link
Member Author

nikku commented Aug 17, 2022

[...] would we also have to follow up with explicit keyboard bindings for the Forms Properties Panel?

Absolutely. Taking it one step at a time here though. Blueprint for properties panel binding can be found here: bpmn-io/bpmn-js-properties-panel#739.

@nikku
Copy link
Member Author

nikku commented Aug 17, 2022

This is now available as a pre-release via diagram-js@9.0.0-alpha.1 and bpmn-js@10.0.0-alpha.1.

nikku added a commit to bpmn-io/bpmn-js-properties-panel that referenced this pull request Aug 17, 2022
This prepares for bpmn-io/diagram-js#662,
but is built in a way that is backwards compatible.
nikku added a commit to bpmn-io/bpmn-js-properties-panel that referenced this pull request Aug 17, 2022
This prepares for bpmn-io/diagram-js#662,
but is built in a way that is backwards compatible.
lib/core/Canvas.js Outdated Show resolved Hide resolved
lib/core/Canvas.js Outdated Show resolved Hide resolved
@jarekdanielak jarekdanielak self-assigned this Oct 17, 2024
@jarekdanielak jarekdanielak marked this pull request as ready for review October 27, 2024 14:46
@bpmn-io-tasks bpmn-io-tasks bot added needs review Review pending and removed backlog Queued in backlog labels Oct 27, 2024
lib/core/Canvas.js Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
lib/features/popup-menu/PopupMenu.js Outdated Show resolved Hide resolved
test/spec/core/CanvasSpec.js Outdated Show resolved Hide resolved
test/spec/features/bendpoints/BendpointsSpec.js Outdated Show resolved Hide resolved
lib/core/Canvas.js Outdated Show resolved Hide resolved
var DEFAULT_PRIORITY = 1000;

var compatMessage = 'Explicit binding of keyboard to an element got removed. For more information, see https://github.com/bpmn-io/diagram-js/issues/661';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var compatMessage = 'Explicit binding of keyboard to an element got removed. For more information, see https://github.com/bpmn-io/diagram-js/issues/661';
var compatMessage = 'Keyboard binding is now implicit; explicit binding to an element got removed. For more information, see https://github.com/bpmn-io/diagram-js/issues/661';

// given
var inputEl = document.createElement('input');

document.body.appendChild(inputEl);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to remove such element after the test, I think.

@@ -1974,7 +1992,7 @@ describe('features/popup-menu', function() {

var y = documentBounds.height - 40;

var cursorPosition = { x: documentBounds.left + 100, y: documentBounds.top + y };
var cursorPosition = { x: documentBounds.left + 100, y };
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this signal a break in behavior, or is this just a test simplification?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs review Review pending
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make keyboard binding implicit / remove ability to bind to any element
7 participants